package com.pangus.toolkits.files.download;

import cn.hutool.core.io.IoUtil;
import com.pangus.toolkits.files.http.Response;
import com.pangus.toolkits.files.model.FileInfo;
import com.pangus.toolkits.files.operation.FSFileOperation;
import com.pangus.toolkits.files.request.Range;
import lombok.Builder;
import okhttp3.ResponseBody;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.function.Supplier;

/**
 * @author yingheng chen
 * @description
 * @date 2019/12/6
 */
@Builder
public class DownLoadTask implements Supplier<PartResult> {
    private int id;
    private String name;
    private DownloadCheckPoint downloadCheckPoint;
    private int partIndex;
    private FileInfo fileInfo;
    private FSFileOperation fileOperation;
    private File tempFile;
    private File cpFile;

    @Override
    public PartResult get() {
        DownloadPart downloadPart = downloadCheckPoint.downloadParts.get(partIndex);
        PartResult tr = new PartResult(partIndex + 1, downloadPart.start, downloadPart.end);
        RandomAccessFile output = null;
        InputStream content = null;
        try {
            output = new RandomAccessFile(tempFile, "rw");
            output.seek(downloadPart.start);
            final Range range = new Range(downloadPart.start, downloadPart.end);
            final Response<ResponseBody> response = fileOperation.downLoad(fileInfo, range);
            content = response.getData().byteStream();
            byte[] buffer = new byte[8 * 1024];
            int bytesRead = 0;
            while ((bytesRead = content.read(buffer)) != -1) {
                output.write(buffer, 0, bytesRead);
            }
            downloadCheckPoint.update(partIndex, true);
            downloadCheckPoint.dump(cpFile);
        } catch (Exception e) {
            tr.setFailed(true);
            tr.setException(e);
        } finally {
            IoUtil.close(output);
            IoUtil.close(content);
        }
        return tr;
    }
}
